﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace Linxiao.SP.Tools.GroupUsersMover.Library
{
    public class GUMSite:IDisposable
    {
        //spSite and spWeb will exist throughout the whole lifetime a GUMSite instance.
        //spsite and spWeb will be disposed by explicitly calling the Dispose method
        private SPSite spSite;
        private SPWeb spWeb;
        private string siteUrl;

        public GUMSite(string siteUrl)
        {
            this.siteUrl = siteUrl;
            LoadSite(siteUrl);
        }

        /// <summary>
        /// Get groups which associated with the current site
        /// </summary>
        /// <returns></returns>
        public IList<SPPrincipal> GetGroups()
        {
            //reload site
            this.LoadSite(siteUrl);

            List<SPPrincipal> principals = new List<SPPrincipal>();

            foreach (SPRoleAssignment roleAssignment in spWeb.RoleAssignments)
            {
                if (roleAssignment.Member is SPGroup)
                {
                    if (GroupUsersManager.HasGroup(roleAssignment.Member.Name, this))
                        principals.Add(roleAssignment.Member);
                }
            }
            return principals;
        }

        /// <summary>
        /// Get SPWeb instance
        /// </summary>
        /// <returns></returns>
        public SPWeb GetSite()
        {
            return spWeb;
        }

        /// <summary>
        /// Move a user group to destination site
        /// </summary>
        /// <param name="groupToMove"></param>
        /// <param name="destinationSite"></param>
        public void MoveGroup(string groupToMove, GUMSite destinationSite)
        {
            if (GroupUsersManager.HasGroupAssociated(groupToMove, destinationSite))
            {
                throw new Exception("The group has been aleady associated with the destination site.");
            } 

            //group does not exist in the destination site collection
            if (!GroupUsersManager.HasGroup(groupToMove, destinationSite))
            {
                //mvoe group first
                GroupUsersManager.MoveGroup(groupToMove, this, destinationSite);
                //move role assignment
                GroupUsersManager.MoveGroupRoleAssignment(groupToMove, this, destinationSite);
            }
            else
            {
                //move role assignment
                GroupUsersManager.MoveGroupRoleAssignment(groupToMove, this, destinationSite);
            }
            
        }

        public void MoveUser(string userToMove, string sourceGroup, string destinationGroup, GUMSite destinationSite)
        { 
            
        }

        /// <summary>
        /// Remove a group associate from current site
        /// </summary>
        /// <param name="groupToRemove"></param>
        public void RemoveGroupRoleAssignment(string groupToRemove)
        {
            GroupUsersManager.RemoveGroupRoleAssignment(this, groupToRemove);
        }

        public void RemoveGroup(string groupToRemove)
        {
            GroupUsersManager.RemoveGroup(this, groupToRemove);
        }

        /// <summary>
        /// Remove a user
        /// </summary>
        /// <param name="userLoginName"></param>
        /// <param name="group"></param>
        public void RemoveUser(string userLoginName, string group)
        {
            GroupUsersManager.RemoveUser(this, userLoginName, group);
        }

        /// <summary>
        /// Dispose end-of-life spSite and spWeb 
        /// </summary>
        public void Dispose()
        {
            if (spSite!=null)
                spSite.Dispose();
            if (spWeb!=null)
                spWeb.Dispose();
        }


        /// <summary>
        /// Load the spSite and spWeb instance
        /// </summary>
        /// <param name="siteUrl"></param>
        private void LoadSite(string siteUrl)
        {
            //validate if the site url is valid
            if (!(siteUrl.StartsWith(@"http://") || siteUrl.StartsWith(@"https://")))
                throw new Exception(@"The site url has to start with http:// or https://");
            
            //spSite and spWeb will be disposed by explicitly call Dispose method
            try
            {
                spSite = new SPSite(siteUrl);
                spWeb = spSite.OpenWeb();

            }
            catch (Exception ex)
            {
                ThrowException("Failed to load site. Please check if the site url is correct.");
            }

            //check if the user has permission to move users/groups
            if (!Utility.IsCurrentUserAuthorised(spWeb))
            {
                ThrowException("The current user has no permission to manage users/groups in this site.");
            }
        }

        private void ThrowException(string errorMessage)
        {
            this.Dispose();
            throw new Exception(errorMessage);
        }


    }
}
